home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / bbsutil / dlx70bbs.zip / DLX70SRC.ZIP / SCRIPT3.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1994-01-26  |  23.0 KB  |  570 lines

  1. {$debug-}
  2. {$line-}
  3.  
  4. {$include: 'types.int'}
  5. {$include: 'globals.int'}
  6. {$include: 'utils.int'}
  7. {$include: 'funs.int'}
  8. {$include: 'fs_pkg.int'}
  9. {$include: 'database.int'}
  10. {$include: 'load.int'}
  11. {$include: 'sutils.int'}
  12. {$include: 'script3.int'}
  13.  
  14. IMPLEMENTATION OF script3;
  15.  
  16. USES types,globals,utils,funs,fs_pkg,database,load,sutils;
  17.  
  18. {DLX Bulletin Board System V7.0
  19.  
  20.  FREEWARE NOTICE
  21.  
  22.  DLX V7.0 is placed in the public domain by its author, Richard Gillmann.
  23.  Anyone who wishes to may run the program, copy it, or modify it for
  24.  any purpose, including commercial gain.}
  25.  
  26. {***Interface to the PASASM assembler utilities package***}
  27. {$include: 'pasasm.int'}
  28.  
  29. procedure bbs3{consts s : lstring; var str : lstring};
  30. var
  31.   i,j,k : integer;
  32.   i4,j4 : integer4;
  33.   next_state : task;
  34.   p : para;
  35.   h : mailhead;
  36.   fl : boolean;
  37.  
  38. begin
  39.   next_state:=succ(q[wx].state);
  40.   case q[wx].state of
  41.   userlog:
  42.     [if (q[wx].count<userlog_entries) and then
  43.         ((q[wx].index<>userlog_next) or (q[wx].count=0)) then
  44.        [q[wx].count:=q[wx].count+1; q[wx].index:=q[wx].index-1;
  45.         if q[wx].index<=0 then q[wx].index:=userlog_entries;
  46.         dbg_userlog(q[wx].index,userlog_buffer);
  47.     if ivalue(userlog_buffer.userlevel)>=priv_log then
  48.           display(userlog_line_txt)
  49.         else
  50.           [if disk2u(ivalue(userlog_buffer.userid)) and then
  51.           ivalue(q[wx].your.userlevel)>=priv_log
  52.              then display(userlog_line_txt)];
  53.         next_state:=userlog]
  54.      else
  55.        next_state:=main_menu];
  56.   sendmail_prompt: prompt_with(file_number_txt);
  57.   sendmail_to:
  58.     [make_number(s,str);
  59.      if number_query(str,1,largest_member_number,i) then
  60.        [q[wx].correspondent:=i;
  61.         if disk2u(i) then
  62.           [i:=ivalue(q[wx].your.mbx_count);
  63.            j:=ivalue(q[wx].your.mbx_max);
  64.            if i<max_max_mbx and then ((i<j) or (q[wx].level=9))
  65.              then display(to_from_txt)
  66.              else [display(no_slots_txt); next_state:=main_menu]]
  67.         else
  68.           [display(bad_userid_txt); next_state:=main_menu]]
  69.      else
  70.        [display(bad_userid_txt); next_state:=main_menu]];
  71.   correct3: prompt_with(cor_txt);
  72.   sendmail_subject:
  73.     if agree(s) then
  74.       [prepare_header; prompt_with(enter_subject_txt)]
  75.     else
  76.       [prompt_with(file_number_txt); next_state:=sendmail_to];
  77.   enter_subject:
  78.     if s.len=0 then
  79.       [display(msg_cancelled_txt); next_state:=sendmail_cancel]
  80.     else
  81.       [p:=newpara(ss[22]); concat(p^.msg,': '); {Subject: }
  82.        cat(p^.msg,s); q[wx].msg_last^.link:=p; q[wx].msg_last:=p;
  83.        p:=newpara(null); q[wx].msg_last^.link:=p; q[wx].msg_last:=p;
  84.        if q[wx].flag
  85.          then display(enter_body_txt)
  86.          else [prompt_with(which_canned_txt); next_state:=canned1]];
  87.   enter_body1:
  88.     [q[wx].send_line_count:=1; q[wx].count:=1; prompt_with(send_line_txt)];
  89.   enter_body2:
  90.     if s[0]=chr(0) then
  91.       [if q[wx].return_state=junk2 then q[wx].index:=largest_member_number;
  92.        display(msg_cancelled_txt); next_state:=sendmail_cancel]
  93.      else
  94.       [p:=newpara(s); q[wx].msg_last^.link:=p; q[wx].msg_last:=p;
  95.        q[wx].send_line_count:=q[wx].send_line_count+1;
  96.        q[wx].count:=q[wx].count+1;
  97.        prompt_with(send_line_txt)];
  98.   enter_body3:
  99.     if s[0]=chr(0) then
  100.       [prompt_with(send_menu_txt); next_state:=sendmail_fork]
  101.     else
  102.       [p:=newpara(s); q[wx].msg_last^.link:=p; q[wx].msg_last:=p;
  103.        q[wx].send_line_count:=q[wx].send_line_count+1;
  104.        q[wx].count:=q[wx].count+1;
  105.        if q[wx].send_line_count<=msg_line_limit or else q[wx].level=9 then
  106.          [prompt_with(send_line_txt); next_state:=enter_body3]
  107.        else
  108.          [prompt_with(send_menu_txt); next_state:=sendmail_fork]];
  109.   sendmail_menu: prompt_with(send_menu_txt);
  110.   sendmail_fork:
  111.     [next_state:=sendmail_menu;
  112.      if str=null then
  113.        display(dunno_txt)
  114.      else if str[1]=mn[10][1] {?} or else eq(str,ss[40]) {HELP} then
  115.        display(send_menu_list_txt)
  116.      else if str.len=1 and then str[1]=mn[10][2] {A} then
  117.        [if q[wx].send_line_count<=msg_line_limit or else q[wx].level=9 then
  118.           [q[wx].count:=q[wx].send_line_count;
  119.            prompt_with(send_line_txt); next_state:=enter_body3]
  120.         else display(too_long_txt)]
  121.      else if str.len=1 and then str[1]=mn[10][9] {D} then
  122.        [prompt_with(delete_line_txt); next_state:=sendmail_delete1]
  123.      else if str.len=1 and then str[1]=mn[10][3] {E} then
  124.        [prompt_with(edit_which_txt); next_state:=sendmail_edit1]
  125.      else if str.len=1 and then str[1]=mn[10][4] {H} and then
  126.           q[wx].return_state<>junk2 then
  127.        [q[wx].holding:=true;
  128.         if q[wx].return_state=pubmail5
  129.           then q[wx].hold_target:=-1
  130.           else q[wx].hold_target:=q[wx].correspondent;
  131.         display(msg_held_txt); next_state:=q[wx].return_state]
  132.      else if str.len=1 and then str[1]=mn[10][5] {L} then
  133.        [prompt_with(what_line_txt); next_state:=sendmail_list]
  134.      else if str.len=1 and then str[1]=mn[10][6] {R} then
  135.        [prompt_with(replace_line_txt); next_state:=sendmail_replace1]
  136.      else if str.len=1 and then str[1]=mn[10][7] {S} then
  137.        case q[wx].return_state of
  138.          pubmail5 : [display(pub_sending_txt); next_state:=sending];
  139.          junk2 : [q[wx].index:=0; q[wx].holding:=false;
  140.                   display(sending_txt); next_state:=junk2];
  141.          otherwise
  142.            [if disk2u(q[wx].correspondent) then
  143.               [display(sending_txt); next_state:=sending]
  144.             else
  145.           [q[wx].dos_err:=-2; {corrupt members file?}
  146.            display(mail_not_sent_txt)]];
  147.        end {case}
  148.      else if str.len=1 and then str[1]=mn[10][8] {X} then
  149.        [if q[wx].return_state=junk2 then q[wx].index:=largest_member_number;
  150.         display(msg_cancelled_txt); next_state:=sendmail_cancel]
  151.      else if eq(str,ss[37]) or else eq(str,ss[38]) or else eq(str,ss[39]) then
  152.        {BYE, OFF, EXIT}
  153.        next_state:=snip
  154.      else if str.len>2 and then
  155.              str[1]=mn[7][2] {/} and then str[2]=mn[7][4] {P} then {/P}
  156.        SlashP(s,str)
  157.      else
  158.        [prompt_with(send_menu_txt); next_state:=sendmail_fork]];
  159.   sendmail_list:
  160.     if s=null or else number_query(s,1,q[wx].send_line_count-1,i) then
  161.       [if s=null then i:=1;
  162.        p:=q[wx].msg_first; q[wx].count:=i;
  163.        for j:=1 to i+4 do
  164.          if p=nill then [q[wx].count:=0; break] else p:=p^.link;
  165.        q[wx].msg_ptr:=p; display(sendmail_line_txt)]
  166.     else
  167.       [display(bad_line_number_txt); next_state:=sendmail_menu];
  168.   sendmail_list2:
  169.     [if q[wx].msg_ptr<>nill then q[wx].msg_ptr:=q[wx].msg_ptr^.link;
  170.      if q[wx].msg_ptr=nill then
  171.        [prompt_with(send_menu_txt); next_state:=sendmail_fork]
  172.      else
  173.        [q[wx].count:=q[wx].count+1;
  174.         display(sendmail_line_txt); next_state:=sendmail_list2]];
  175.   sendmail_edit1:
  176.     if number_query(s,1,q[wx].send_line_count-1,i) then
  177.       [p:=q[wx].msg_first; q[wx].count:=i;
  178.        for j:=1 to i+4 do
  179.          if p=nill then [q[wx].count:=0; break] else p:=p^.link;
  180.        q[wx].msg_ptr:=p; display(sendmail_line_txt)]
  181.     else
  182.       [display(bad_line_number_txt); next_state:=sendmail_menu];
  183.   sendmail_edit2: prompt_with(enter_new_line_txt);
  184.   sendmail_edit3:
  185.     [kopylst(s,q[wx].msg_ptr^.msg);
  186.      prompt_with(send_menu_txt); next_state:=sendmail_fork];
  187.   sendmail_replace1:
  188.     if number_query(s,1,q[wx].send_line_count-1,i) then
  189.       [p:=q[wx].msg_first; q[wx].count:=i;
  190.        for j:=1 to i+4 do
  191.          if p=nill then [q[wx].count:=0; break] else p:=p^.link;
  192.        q[wx].msg_ptr:=p; display(sendmail_line_txt)]
  193.     else
  194.       [display(bad_line_number_txt); next_state:=sendmail_menu];
  195.   sendmail_replace2: prompt_with(text_old_txt);
  196.   sendmail_replace3:
  197.     [if q[wx].verify_data=nill
  198.        then q[wx].verify_data:=newpara(s)
  199.        else kopylst(s,q[wx].verify_data^.msg);
  200.      prompt_with(text_new_txt)];
  201.   sendmail_replace4: {msg_ptr = original text, verify_data = old, s = new}
  202.     [if q[wx].msg_ptr<>nill and then q[wx].verify_data<>nill then
  203.        [k:=0;
  204.         for i:=1 to ord(q[wx].msg_ptr^.msg.len) do begin
  205.           fl:=true;
  206.           for j:=1 to ord(q[wx].verify_data^.msg.len) do
  207.             if i+j-1>ord(q[wx].msg_ptr^.msg.len) or else
  208.                q[wx].msg_ptr^.msg[i+j-1]<>q[wx].verify_data^.msg[j]
  209.               then [fl:=false; break];
  210.           if fl then
  211.             [k:=i; break];
  212.         end {for};
  213.         if fl then
  214.           [copylst(q[wx].msg_ptr^.msg,str);
  215.            if k+ord(s.len)-1<=UPPER(str) then
  216.              [if str.len+s.len-q[wx].verify_data^.msg.len>wrd(UPPER(str)) then
  217.                 str.len:=wrd(UPPER(str))-s.len+q[wx].verify_data^.msg.len;
  218.               replace(str,s,k,ord(q[wx].verify_data^.msg.len));
  219.               kopylst(str,q[wx].msg_ptr^.msg)]]];
  220.      prompt_with(send_menu_txt); next_state:=sendmail_fork];
  221.   sendmail_delete1:
  222.     if number_query(s,1,q[wx].send_line_count-1,i) then
  223.       [p:=q[wx].msg_first; q[wx].count:=i;
  224.        for j:=1 to i+4 do
  225.          if p=nill then [q[wx].count:=0; break] else p:=p^.link;
  226.        q[wx].msg_ptr:=p; display(sendmail_line_txt)]
  227.     else
  228.       [display(bad_line_number_txt); next_state:=sendmail_menu];
  229.   sendmail_delete2: prompt_with(cor_txt);
  230.   sendmail_delete3:
  231.     if agree(s) and then q[wx].count>0 then
  232.       [if q[wx].send_line_count<=2 then
  233.          [if q[wx].return_state=junk2 then q[wx].index:=largest_member_number;
  234.           display(msg_cancelled_txt); next_state:=sendmail_cancel]
  235.        else
  236.          [p:=q[wx].msg_first;
  237.           for j:=1 to q[wx].count+3 do
  238.             if p=nill then break else p:=p^.link;
  239.           if p<>nill and then p^.link<>nill then
  240.             [q[wx].msg_ptr:=p^.link; p^.link:=q[wx].msg_ptr^.link;
  241.          if p^.link=nill then q[wx].msg_last:=p;
  242.              display(line_deleted_txt);
  243.              dispara(q[wx].msg_ptr); q[wx].msg_ptr:=nill;
  244.              q[wx].send_line_count:=q[wx].send_line_count-1];
  245.           next_state:=sendmail_menu]]
  246.     else
  247.      [prompt_with(send_menu_txt); next_state:=sendmail_fork];
  248.   sending:
  249.     [q[wx].holding:=false; eval(disk2u(q[wx].correspondent)); {OK if false}
  250.      if q[wx].return_state=pubmail5 then
  251.        [if not q[wx].pm^.holdem or else
  252.            q[wx].pm^.memberid=q[wx].userid or else q[wx].level=9 then
  253.           [if dbp_pubmail(q[wx].msg_first,' ')
  254.              then [q[wx].msg_first:=nill; q[wx].msg_last:=nill;
  255.                    display(pubmail_sent_txt)]
  256.              else display(mail_not_sent_txt)]
  257.         else
  258.           [if dbp_pubmail(q[wx].msg_first,'H')
  259.              then [q[wx].msg_first:=nill; q[wx].msg_last:=nill;
  260.                    display(pubmail_held_txt)]
  261.              else display(mail_not_sent_txt)];
  262.         if q[wx].current_msg=0
  263.           then next_state:=q[wx].return_state
  264.           else next_state:=pub_rfb4]
  265.      else
  266.        [if sendmsg then
  267.           [display(mail_sent_txt);
  268.            if q[wx].return_state=readmail_menu
  269.              then next_state:=reply_deletes
  270.              else next_state:=q[wx].return_state]
  271.         else
  272.           [display(mail_not_sent_txt); next_state:=sendmail_menu]]];
  273.   reply_deletes:
  274.     if auto_delete then
  275.       [q[wx].mbx_ptr^.deleted:=true; q[wx].mail_mod:=true;
  276.        display(msg_deleted_txt); next_state:=which_msg_menu]
  277.     else
  278.       next_state:=q[wx].return_state;
  279.   sendmail_cancel:
  280.     [q[wx].holding:=false;
  281.      disparas(q[wx].msg_first); q[wx].msg_last:=nill; q[wx].msg_ptr:=nill;
  282.      next_state:=q[wx].return_state];
  283.   mail_gimme1:
  284.     [i4:=mem_avl-lhc; j4:=mbi; i4:=i4-j4;
  285.      if fs_eof(wx) then {done reading mail}
  286.        [if encode(str,q[wx].index:1) then kopystr(str,q[wx].my.mbx_count);
  287.         fs_close(wx);
  288.         if q[wx].my.junk[1]<>' '
  289.           then next_state:=mail_gimme1j
  290.           else next_state:=which_msg_menu]
  291.      else if i4<(mem_avl div 20) then {running out of memory}
  292.        [if encode(str,q[wx].index:1) then kopystr(str,q[wx].my.mbx_count);
  293.         fs_close(wx);
  294.         display(ofl_txt); next_state:=which_msg_menu]
  295.      else if fs_gets(wx,str)<>0 or else (not decode(str,q[wx].count)) then
  296. {damaged mail file}
  297.        [if encode(str,q[wx].index:1) then kopystr(str,q[wx].my.mbx_count);
  298.         fs_close(wx); q[wx].mail_mod:=true;
  299.         q[wx].count:=14; display(file_error_txt);
  300.         if q[wx].my.junk[1]<>' '
  301.           then next_state:=mail_gimme1j
  302.           else next_state:=which_msg_menu]
  303.      else {good letter to read}
  304.        [q[wx].index:=q[wx].index+1;
  305.         newhead(h); h^.head_link:=nil;
  306.         h^.text_first:=nill; h^.text_last:=nill;
  307.         h^.index:=q[wx].index; h^.deleted:=false;
  308.         if q[wx].mbx_first=nil then
  309.           [q[wx].mbx_first:=h; q[wx].mbx_last:=h]
  310.         else
  311.           [q[wx].mbx_last^.head_link:=h; q[wx].mbx_last:=h]]];
  312.   mail_gimme2:
  313.     if fs_eof(wx) or else q[wx].count=0 then
  314.       [q[wx].current_msg:=q[wx].index;
  315.        if q[wx].current_msg=1
  316.          then q[wx].mbx_ptr:=q[wx].mbx_first
  317.          else q[wx].mbx_ptr:=q[wx].mbx_ptr^.head_link;
  318.        parse_header(q[wx].mbx_ptr^.text_first);
  319.        display(msg_header_txt); next_state:=mail_gimme1]
  320.     else
  321.       [if fs_gets(wx,str)=0
  322.          then q[wx].count:=q[wx].count-1
  323.          else q[wx].count:=0;
  324.        fSmall:=true; p:=newpara(str); fSmall:=false;
  325.        if q[wx].mbx_last^.text_first=nill
  326.          then q[wx].mbx_last^.text_first:=p
  327.          else q[wx].mbx_last^.text_last^.link:=p;
  328.        q[wx].mbx_last^.text_last:=p;
  329.        next_state:=mail_gimme2];
  330.   mail_gimme1j:
  331.     [kopylst(mailpath,str);
  332.      if q[wx].my.junk[1]='J'
  333.        then konkat(str,d_junk)
  334.        else konkat(str,d_new);
  335.      q[wx].my.junk[1]:=' '; q[wx].mail_mod:=true;
  336.      q[wx].count:=fs_openr(wx,str);
  337.      if q[wx].count=0 then {file opened OK}
  338.        next_state:=mail_gimme1
  339.      else
  340.        [fs_close(wx);
  341.         if q[wx].index>0 {index = no. of messages all told}
  342.           then [prompt_with(which_msg_txt); next_state:=which_msg_fork]
  343.           else [display(no_mail_txt); next_state:=main_menu]]];
  344.   readmail_header:
  345.     [q[wx].current_msg:=q[wx].current_msg+1;
  346.      if q[wx].current_msg>q[wx].count then
  347.        [prompt_with(which_msg_txt); next_state:=which_msg_fork]
  348.      else
  349.        [if q[wx].current_msg=1
  350.           then q[wx].mbx_ptr:=q[wx].mbx_first
  351.           else q[wx].mbx_ptr:=q[wx].mbx_ptr^.head_link;
  352.         parse_header(q[wx].mbx_ptr^.text_first);
  353.         if q[wx].mbx_ptr^.deleted
  354.           then display(msg_header_deleted_txt)
  355.           else display(msg_header_txt);
  356.         next_state:=readmail_header]];
  357.   which_msg_menu: prompt_with(which_msg_txt);
  358.   which_msg_fork:
  359.     [next_state:=which_msg_menu;
  360.      if s=null or else str[1]=mn[8][3] {Q} then
  361.        [if q[wx].level<9
  362.           then [display(room_for_txt); next_state:=main_menu]
  363.           else next_state:=main_menu]
  364.      else if time_check(true) then
  365.        [display(time_limit_txt); next_state:=snip]
  366.      else if s[1]=mn[8][1] {?} then
  367.        [q[wx].current_msg:=0; q[wx].count:=ivalue(q[wx].my.mbx_count);
  368.         display(msg_title_txt); next_state:=readmail_header]
  369.      else if number_query(s,1,ivalue(q[wx].my.mbx_count),i) then
  370.        [q[wx].current_msg:=i;
  371.         q[wx].mbx_ptr:=q[wx].mbx_first;
  372.         while q[wx].mbx_ptr^.index<>q[wx].current_msg do
  373.           q[wx].mbx_ptr:=q[wx].mbx_ptr^.head_link;
  374.         if q[wx].mbx_ptr^.deleted then
  375.           [prompt_with(undelete_prompt_txt); next_state:=undelete]
  376.         else
  377.           [display(fetching_txt); next_state:=readtext]]
  378.      else
  379.        display(invalid_msg_txt)];
  380.   undelete:
  381.     if nagree(s) then
  382.       [q[wx].mbx_ptr^.deleted:=false; display(msg_undeleted_txt)]
  383.     else
  384.       [prompt_with(which_msg_txt); next_state:=which_msg_fork];
  385.   fetching: display(fetching_txt);
  386.   readtext:
  387.     [parse_header(q[wx].mbx_ptr^.text_first);
  388.      display(q[wx].mbx_ptr^.text_first)];
  389.   readmail_menu: prompt_with(read_menu_txt);
  390.   readmail_fork:
  391.     [next_state:=readmail_menu;
  392.      if time_check(true) then
  393.        [display(time_limit_txt); next_state:=snip]
  394.      else if str=null then
  395.        [prompt_with(which_msg_txt); next_state:=which_msg_fork]
  396.      else if str[1]=mn[11][1] {?} then
  397.        [prompt_with(read_menu_txt); next_state:=readmail_fork]
  398.      else if str.len=1 and then str[1]=mn[11][2] {B} then
  399.        [if q[wx].level<priv_br then
  400.           display(read_access_txt)
  401.         else if disk2u(q[wx].correspondent) then
  402.           [display(browse_txt);
  403.            q[wx].return_state:=readmail_menu; next_state:=browse_qs1]
  404.         else display(bad_userid_txt)]
  405.      else if str.len=1 and then str[1]=mn[11][3] {D} then
  406.        [q[wx].mbx_ptr^.deleted:=true; q[wx].mail_mod:=true;
  407.         display(msg_deleted_txt); next_state:=which_msg_menu]
  408.      else if str.len=1 and then str[1]=mn[11][4] {R} then {Reply to private}
  409.        [q[wx].return_state:=readmail_menu;
  410.         if disk2u(q[wx].correspondent) then
  411.       [if q[wx].level<priv_reply then
  412.          display(read_access_txt)
  413.        else if q[wx].holding then
  414.          [if q[wx].correspondent=q[wx].hold_target
  415.         then [display(send_private_txt); next_state:=sendmail_menu]
  416.         else display(hold_error_txt)]
  417.        else if ivalue(q[wx].your.mbx_count)<ivalue(q[wx].your.mbx_max)
  418.            or else q[wx].level=9 then
  419.          [q[wx].flag:=true; {normal reply}
  420.           display(send_private_txt); next_state:=reply1]
  421.        else
  422.          display(no_slots_txt)]
  423.     else
  424.           display(user_deleted_txt)]
  425.      else if str.len=1 and then str[1]=mn[11][5] {S} then {See it again}
  426.        [display(fetching_txt); next_state:=readtext]
  427.      else if str.len>2 and then
  428.              str[1]=mn[7][2] {/} and then str[2]=mn[7][4] {P} then {/P}
  429.        SlashP(s,str)
  430.      else if q[wx].level=9 then begin
  431.      if str='!C' and then (not q[wx].holding) then {canned reply}
  432.        [q[wx].return_state:=readmail_menu;
  433.         if disk2u(q[wx].correspondent) then
  434.       [q[wx].flag:=false; {canned reply}
  435.        display(send_private_txt); next_state:=reply1]
  436.     else
  437.           display(user_deleted_txt)]
  438.      else if str='!D' then
  439.        [if disk2u(q[wx].correspondent) then
  440.           [q[wx].return_state:=readmail_menu;
  441.            prompt_with(user_delete_txt); next_state:=delete_user2]
  442.         else
  443.           [display(bad_userid_txt); next_state:=readmail_menu]]
  444.      else if str='!L' then
  445.        [if disk2u(q[wx].correspondent) then
  446.           [q[wx].return_state:=readmail_menu;
  447.            prompt_with(enter_level_txt); next_state:=change_level2]
  448.         else
  449.           [display(bad_userid_txt); next_state:=readmail_menu]]
  450.      else if str='!M' then
  451.        [if disk2u(q[wx].correspondent) then
  452.           [q[wx].return_state:=readmail_menu;
  453.            prompt_with(mbx_size_txt); next_state:=change_mbx2]
  454.         else
  455.           [display(bad_userid_txt); next_state:=readmail_menu]]
  456.      else if str='!T' then
  457.        [if disk2u(q[wx].correspondent) then
  458.           [q[wx].return_state:=readmail_menu;
  459.            prompt_with(reset_time_txt); next_state:=reset_time]
  460.         else
  461.           [display(bad_userid_txt); next_state:=readmail_menu]]
  462.      else [prompt_with(which_msg_txt); next_state:=which_msg_fork] end
  463.      else [prompt_with(which_msg_txt); next_state:=which_msg_fork]];
  464.   reply1: display(to_from_txt);
  465.   reply2:
  466.     [if not eq2(q[wx].msg_subject^.msg,ss[49]) {Re:} then
  467.        [copylst(ss[49],str); cat(str,q[wx].msg_subject^.msg);
  468.         kopylst(str,q[wx].msg_subject^.msg)];
  469.      display(subject_txt)];
  470.   reply2a: prompt_with(cor_txt);
  471.   reply2b:
  472.     if s.len>3 then
  473.       [kopylst(s,q[wx].msg_subject^.msg);
  474.        display(subject_txt); next_state:=reply2a]
  475.     else if agree(s) then
  476.        next_state:=reply3
  477.     else
  478.        prompt_with(enter_subject_txt);
  479.   reply2c:
  480.     if s[0]=chr(0)
  481.       then [display(msg_cancelled_txt); next_state:=sendmail_cancel]
  482.       else kopylst(s,q[wx].msg_subject^.msg);
  483.   reply3:
  484.     [prepare_header;
  485.      p:=newpara(ss[22]); concat(p^.msg,': '); {Subject: }
  486.      cat(p^.msg,q[wx].msg_subject^.msg);
  487.      q[wx].msg_last^.link:=p; q[wx].msg_last:=p;
  488.      p:=newpara(null); q[wx].msg_last^.link:=p; q[wx].msg_last:=p;
  489.      if q[wx].flag
  490.        then [display(enter_body_txt); next_state:=enter_body1]
  491.        else prompt_with(which_canned_txt)];
  492.   canned1:
  493.     if str=null or else (not filename_ok(str)) then
  494.       [display(msg_cancelled_txt); next_state:=sendmail_cancel]
  495.     else
  496.       [q[wx].count:=fs_openr(wx,str);
  497.        if q[wx].count=0 then
  498.          q[wx].send_line_count:=1
  499.        else
  500.          [fs_close(wx);
  501.           display(msg_cancelled_txt); next_state:=sendmail_cancel]];
  502.   canned2:
  503.     if fs_eof(wx) then
  504.       [fs_close(wx);
  505.        prompt_with(send_menu_txt); next_state:=sendmail_fork]
  506.     else
  507.       [p:=newpara(null); q[wx].msg_last^.link:=p; q[wx].msg_last:=p;
  508.        q[wx].send_line_count:=q[wx].send_line_count+1;
  509.        q[wx].count:=fs_gets(wx,p^.msg);
  510.        if q[wx].count=0 then
  511.          [expand_tabs(p^.msg); init_fx;
  512.           if not substitute(p^.msg) then
  513.             [kopylst(p^.msg,str); eval(substitute(str));
  514.              kopylst(str,p^.msg)];
  515.           next_state:=canned2]
  516.        else
  517.          [fs_close(wx);
  518.           display(io_error_txt); next_state:=sendmail_menu]];
  519.   pubmail1: {entry to public mail from the main menu}
  520.     [q[wx].pm:=pubmail;
  521.      if q[wx].pm=nil then
  522.        next_state:=main_menu
  523.      else if see_pub then
  524.        display(pubmail_line_txt)];
  525.   pubmail2: {display one pubmail header and loop}
  526.     [repeat q[wx].pm:=q[wx].pm^.link until q[wx].pm=nil or else see_pub;
  527.      if q[wx].pm=nil
  528.        then display(pubmail_trailer_txt)
  529.        else [display(pubmail_line_txt); next_state:=pubmail2]];
  530.   pubmail3: prompt_with(select_category_txt);
  531.   pubmail4: {select a category}
  532.     [if time_check(true) then
  533.        [display(time_limit_txt); next_state:=snip]
  534.      else if str=null then
  535.        next_state:=main_menu
  536.      else if str[1]=mn[8][1] {?} or else eq(str,ss[40]) then {HELP}
  537.        [display(pubmail_header_txt); next_state:=pubmail1]
  538.      else
  539.        [q[wx].pm:=pubmail;
  540.         while q[wx].pm<>nil and then
  541.           ((q[wx].pm^.letter[1]<>str[1]) or (not see_pub)) do
  542.           q[wx].pm:=q[wx].pm^.link;
  543.         if q[wx].pm=nil and then str[1]=mn[12][9] {N} then
  544.           [q[wx].pm:=pubmail;
  545.            while q[wx].pm<>nil and then (not see_pub) do
  546.          q[wx].pm:=q[wx].pm^.link];
  547.         if q[wx].pm=nil then
  548.           [if str[1]=mn[8][3] {Q}
  549.              then next_state:=main_menu
  550.              else [display(bad_category_txt); next_state:=pubmail3]]
  551.         else
  552.           [if q[wx].pm^.qaire<>0 and then
  553.               q[wx].my.mult_answer[ord(q[wx].pm^.qaire)][1]=' '
  554.              then prompt_with(special_qaire_txt)
  555.              else [prompt_with(pubcat_menu_txt); next_state:=pubmail6]]]];
  556.   pubmail4a: {answer special questionnaire}
  557.     if nagree(s) then
  558.       [q[wx].qr:=ord(q[wx].pm^.qaire); q[wx].qs:=qair[q[wx].qr];
  559.        q[wx].index:=1; q[wx].return_state:=pubmail5;
  560.        display(nextq_txt); next_state:=mult_ch1a]
  561.     else
  562.       [if q[wx].pm^.mandatory and then q[wx].level<9
  563.          then [prompt_with(select_category_txt); next_state:=pubmail4]
  564.          else [prompt_with(pubcat_menu_txt); next_state:=pubmail6]];
  565.   end {case};
  566.   q[wx].state:=next_state;
  567. end {bbs3};
  568.  
  569. END.
  570.